﻿using LitJson;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GoBangController_Tcp : IGoBangController
{
    private static GoBangController_Tcp m_Inst;
    public static GoBangController_Tcp Instance
    {
        get
        {
            if (null == m_Inst)
                m_Inst = new GoBangController_Tcp();
            return m_Inst;
        }
    }

    private GoBangTest m_View;

    private bool m_ServerReady = false;
    private bool m_ClientReady = false;

    public bool m_SelfIsServer = false;
    public string m_GameKey = "";

    public void OnDestroy()
    {
        RegistMsg(false);
    }

    public void OnEnable(GoBangTest view)
    {
        m_View = view;

        m_View.m_BtnReady.onClick.AddListener(OnClick_Ready);
        RegistMsg(true);
        ShowNotReady();
    }

    public void OnDisable()
    {
        m_View.m_BtnReady.onClick.RemoveListener(OnClick_Ready);
        RegistMsg(false);
        m_GameKey = "";
        m_View = null;
    }

    private void RegistMsg(bool b)
    {
        if (b)
        {
            MsgDispatch.Instance.AddReceiver("ReadyNoti", OnMsg_ReadyNoti);
            MsgDispatch.Instance.AddReceiver("StartNoti", OnMsg_StartNoti);
            MsgDispatch.Instance.AddReceiver("ChessDownNoti", OnMsg_ChessDownNoti);
            MsgDispatch.Instance.AddReceiver("GiveUp", OnMsg_GiveUp);
            MsgDispatch.Instance.AddReceiver("Leave", OnMsg_Leave);

            MsgDispatch.Instance.AddReceiver("Join.Server", OnMsgServer_Join);
            MsgDispatch.Instance.AddReceiver("Ready.Server", OnMsgServer_Ready);
            MsgDispatch.Instance.AddReceiver("ChessDown.Server", OnMsgServer_ChessDown);
        }
        else
        {
            MsgDispatch.Instance.RemoveReceivers(this);
        }
    }

    public void OnWaitStart()
    {
        ShowNotReady();
    }

    private void ShowNotReady()
    {
        m_ServerReady = false;
        m_ClientReady = false;
        m_View.m_TxtClientTurn.enabled = false;
        m_View.m_TxtServerTurn.enabled = false;

        if (m_SelfIsServer)
        {
            m_View.m_MyChessColor = 1;
            m_View.m_TxtServerName.text = "黑棋(自己)";
            m_View.m_TxtClientName.text = "白棋(未准备)";
        }
        else
        {
            m_View.m_MyChessColor = 2;
            m_View.m_TxtServerName.text = "黑棋(未准备)";
            m_View.m_TxtClientName.text = "白棋(自己)";
        }
        m_View.m_BtnReady.gameObject.SetActive(true);
        m_View.m_BtnReady.GetComponentInChildren<Text>().text = "准备";
        m_View.m_TxtCDTime.text = "未开始";
    }

    public void OnDownChess(int turnFlag, int row, int col)
    {
        if (1 == turnFlag)
        {
            NetManager.Instance.ServerSendChessDownNoti(turnFlag, row, col);
        }
        else if (2 == turnFlag)
        {
            NetManager.Instance.ClientSendChessDown(turnFlag, row, col);
        }
    }

    public void OnUpdate()
    {

    }

    public void OnLeftTimeUp()
    {

    }

    public void OnNextTurn()
    {

    }

    private void OnClick_Ready()
    {
        if (m_SelfIsServer)
            OnClick_ServerReady();
        else
            OnClick_ClientReady();
    }

    private void OnClick_ServerReady()
    {
        if (0 != m_View.m_Status) return;
        if (m_ServerReady && m_ClientReady) return;

        m_ServerReady = !m_ServerReady;

        if (m_ServerReady && m_ClientReady) //服务器后准备好
        {
            ServerSendStartNoti();
        }
        else
        {
            //通知房间内的人: 有人Ready
            var sendData = new JsonData();
            sendData["msg"] = "ReadyNoti";
            sendData["color"] = 1;
            sendData["b"] = m_ServerReady;

            OnMsg_ReadyNoti("ReadyNoti", sendData);
            NetManager.Instance.SendToClient(sendData.ToJson());
        }
    }

    private void OnClick_ClientReady()
    {
        if (0 != m_View.m_Status) return;
        if (m_ServerReady && m_ClientReady) return;

        if (m_ClientReady)
        {
            m_View.m_BtnReady.GetComponentInChildren<Text>().text = "准备";
        }
        else
        {
            m_View.m_BtnReady.GetComponentInChildren<Text>().text = "取消准备";
        }
        m_ClientReady = !m_ClientReady;

        NetManager.Instance.ClientSendReady(m_ClientReady);
    }

    //******************** message server

    public void OnMsgServer_Join(string msgName, object obj)
    {
        JsonData data = (JsonData)obj;
        var key = (string)data["key"];
        key = key.Trim();

        var sendData = new JsonData();
        sendData["msg"] = "Join";
        if (string.IsNullOrEmpty(key) || key != m_GameKey)
        {
            sendData["code"] = 1; //密令错误
            NetManager.Instance.SendToClient(sendData.ToJson());
            return;
        }

        sendData["code"] = 0;
        NetManager.Instance.SendToClient(sendData.ToJson());

        //通知房间内的人: 有人加入
        sendData = new JsonData();
        sendData["msg"] = "JoinNoti";
        sendData["black"] = m_ServerReady;
        sendData["white"] = false;
        //OnMsg_JoinNoti(sendData);
        NetManager.Instance.SendToClient(sendData.ToJson());
    }

    private void OnMsgServer_Ready(string msgName, object obj)
    {
        JsonData data = (JsonData)obj;
        bool clientReady = (bool)data["b"];
        if (m_ServerReady && clientReady) //客户端后准备好
        {
            ServerSendStartNoti();
        }
        else
        {
            //通知房间内的人: 有人Ready
            OnMsg_ReadyNoti("ReadyNoti", obj);
            NetManager.Instance.SendToClient(data.ToJson());
        }
    }

    private void OnMsgServer_ChessDown(string msgName, object obj)
    {
        JsonData data = (JsonData)obj;
        int turn = (int)data["turn"];
        if (m_View.m_TurnFlag != turn)
        {
            Debug.LogError($"ChessDown: turn err: {turn}");
            var sendData = new JsonData();
            sendData["msg"] = "ChessDown";
            sendData["code"] = 1; //not your turn
            sendData["turn"] = m_View.m_TurnFlag;
            NetManager.Instance.SendToClient(sendData.ToJson());
            return;
        }

        //通知房间内的人: 有人落子
        OnMsg_ChessDownNoti("ChessDownNoti", obj);
        NetManager.Instance.SendToClient(data.ToJson());
    }

    //********************

    private void ServerSendStartNoti()
    {
        var sendData = new JsonData();
        sendData["msg"] = "StartNoti";

        var j_gridChess = new JsonData();
        j_gridChess.SetJsonType(JsonType.Array);
        for (int row = 0; row < m_View.m_GridChess.Length; ++row)
        {
            var j_gridChessRow = new JsonData();
            j_gridChessRow.SetJsonType(JsonType.Array);
            j_gridChess.Add(j_gridChessRow);

            for (int col = 0; col < m_View.m_GridChess[0].Length; ++col)
            {
                int chessColor = m_View.m_GridChess[row][col];
                j_gridChessRow.Add(chessColor);
            }
        }
        sendData["gridChess"] = j_gridChess;
        sendData["chessCount"] = m_View.m_ChessCount;
        sendData["turn"] = m_View.m_TurnFlag;
        sendData["lastRow"] = m_View.m_LastChessDownRow;
        sendData["lastCol"] = m_View.m_LastChessDownCol;

        OnMsg_StartNoti("StartNoti", sendData);
        //通知房间内的人: 开始
        NetManager.Instance.SendToClient(sendData.ToJson());
    }

    //******************** message 



    //有人的ready变化
    public void OnMsg_ReadyNoti(string msgName, object obj)
    {
        JsonData data = (JsonData)obj;
        int color = (int)data["color"];
        bool ready = (bool)data["b"];

        if (1 == color)
        {
            m_ServerReady = ready;

            if (m_View.m_MyChessColor == color)
            {
                if (ready)
                    m_View.m_BtnReady.GetComponentInChildren<Text>().text = "取消准备";
                else
                    m_View.m_BtnReady.GetComponentInChildren<Text>().text = "准备";
            }
            else
            {
                if (ready)
                    m_View.m_TxtServerName.text = "黑棋(已准备)";
                else
                    m_View.m_TxtServerName.text = "黑棋(未准备)";
            }
        }
        else if (2 == color)
        {
            m_ClientReady = ready;

            if (m_View.m_MyChessColor == color)
            {
                if (ready)
                    m_View.m_BtnReady.GetComponentInChildren<Text>().text = "取消准备";
                else
                    m_View.m_BtnReady.GetComponentInChildren<Text>().text = "准备";
            }
            else
            {
                if (ready)
                    m_View.m_TxtClientName.text = "白棋(已准备)";
                else
                    m_View.m_TxtClientName.text = "白棋(未准备)";
            }
        }
    }

    //开始
    private void OnMsg_StartNoti(string msgName, object obj)
    {
        JsonData data = (JsonData)obj;
        m_View.m_LeftTime = 15;
        if (0 != m_View.m_Status) //重新加入
        {
            Debug.LogError($"StartNoti: status != 0");
            return;
        }

        if (!m_SelfIsServer)
        {
            var j_gridChess = data["gridChess"];
            for (int row = 0; row < j_gridChess.Count; ++row)
            {
                var j_gridChessRow = j_gridChess[row];
                for (int col = 0; col < j_gridChessRow.Count; ++col)
                {
                    int chessColor = (int)j_gridChessRow[col];
                    m_View.m_GridChess[row][col] = chessColor;
                    if (0 != chessColor)
                    {
                        m_View.AddChessGameObject(row, col, chessColor);
                    }
                    else
                    {
                        var chessTrans = m_View.m_BoardTrans.Find($"chess_{row}_{col}");
                        if (null != chessTrans && chessTrans.gameObject.activeSelf)
                        {
                            chessTrans.gameObject.SetActive(false);
                            m_View.m_ChessObjPool.Enqueue((RectTransform)chessTrans);
                        }
                    }
                }
            }

            m_View.MoveOutChessDownHint();

            m_View.m_ChessCount = (int)data["chessCount"];
            m_View.m_LastChessDownRow = (int)data["lastRow"];
            m_View.m_LastChessDownCol = (int)data["lastCol"];

            m_View.m_TurnFlag = (int)data["turn"];
        }

        m_ServerReady = true;
        m_ClientReady = true;
        m_View.m_BtnReady.gameObject.SetActive(false);
        if (m_SelfIsServer)
            m_View.m_TxtClientName.text = "白棋";
        else
            m_View.m_TxtServerName.text = "黑棋";
        m_View.UpdateTurnHint();

        m_View.m_Status = 1;
    }

    

    //有人落子
    private void OnMsg_ChessDownNoti(string msgName, object obj)
    {
        JsonData data = (JsonData)obj;
        int turn = (int)data["turn"];
        if (m_View.m_MyChessColor == turn) return; //直接本地落子了

        int col = (int)data["x"];
        int row = (int)data["y"];
        m_View.DownChess(row, col);
    }

    private void OnMsg_GiveUp(string msgName, object obj)
    {

    }

    private void OnMsg_Leave(string msgName, object obj)
    {

    }

    //********************

}
